#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    statusBar()->showMessage("welcome to shark!");
    ui->toolBar->addAction(ui->actionrunandstop);
    ui->toolBar->addAction(ui->actionclear);
    countNumber = 0;
    numberRow = -1;
    showNetworkCard();

    multhread *thread = new multhread;
    static bool index = false;

    connect(ui->actionrunandstop, &QAction::triggered, this, [=](){
        index=!index;
        if(index)
        {
            QVector<DataPackAge>().swap(pData);
            int res = capture();
            if(res != -1 && pointer)
            {
                ui->tableWidget->clearContents();
                ui->tableWidget->setRowCount(0);
                countNumber = 0;

                int dataSize = this->pData.size();
                for(int i = 0; i<dataSize;i++)
                {
                    free((char*)(this->pData[i].pkt_content));
                    this->pData[i].pkt_content = nullptr;
                }

                thread->setPointer(pointer);
                thread->setFlag();
                thread->start();
                ui->actionrunandstop->setIcon(QIcon(":/res/stop.png"));
                ui->comboBox->setEnabled(false);
            }
            else
            {
                index = !index;
                countNumber = 0;
            }
        }
        else
        {
            thread->resetFlag();
            thread->quit();
            thread->wait();
            ui->actionrunandstop->setIcon(QIcon(":/res/start.png"));
            ui->comboBox->setEnabled(true);
            pcap_close(pointer);
            pointer = nullptr;
        }
    });

    connect(thread, &multhread::send, this, &MainWindow::HandleMessage);

    ui->toolBar->setMovable(false);
    ui->tableWidget->setColumnCount(7);
    ui->tableWidget->verticalHeader()->setDefaultSectionSize(30);
    QStringList title = {"NO.","TIME","Source","Destination","Protocol","Length","Info"};

    ui->tableWidget->setHorizontalHeaderLabels(title);
    ui->tableWidget->setColumnWidth(0, 50);
    ui->tableWidget->setColumnWidth(1, 150);
    ui->tableWidget->setColumnWidth(2, 300);
    ui->tableWidget->setColumnWidth(3, 300);
    ui->tableWidget->setColumnWidth(4, 100);
    ui->tableWidget->setColumnWidth(5, 100);
    ui->tableWidget->setColumnWidth(6, 1000);

    ui->tableWidget->setShowGrid(false);
    ui->tableWidget->verticalHeader()->setVisible(false);
    ui->tableWidget->setSelectionBehavior(QAbstractItemView::SelectRows);
    ui->treeWidget->setHeaderHidden(true);

    connect(ui->actionclear, &QAction::triggered, this, [=](){
        pData.clear();
        countNumber = 0;
        numberRow = -1;
        ui->tableWidget->clearContents();
        ui->tableWidget->setRowCount(0);
        ui->treeWidget->clear();
    });

    this->sender = new sendIcmp();
    ui->lineEdit_2->setText(TRACE_EXAMPLE);
    ui->lineEdit_3->setText(QString::number(ICMP_MAX_HOP));
    ui->lineEdit_4->setText(QString::number(ICMP_MAX_TIMEOUT));
    ui->lineEdit_7->setText(QString(PADDING_LETTER));
    connect(sender, &sendIcmp::send, this, &MainWindow::icmpHandleMessage);

    this->http = new httpRequest;
    connect(http, &httpRequest::httpSend, this, &MainWindow::httpHandleMessage);

    ui->tableWidget->viewport()->installEventFilter(this);
    // 连接数据添加信号到槽
    //connect(dataSource, &DataSource::dataAdded, this, &MainWindow::HandleMessage);
}

MainWindow::~MainWindow()
{
    int dataSize = pData.size();
    for(int i = 0; i<dataSize; i++)
    {
        free((char*)this->pData[i].pkt_content);
        this->pData[i].pkt_content = nullptr;
    }

    QVector<DataPackAge>().swap(pData);

    delete ui;
}

bool MainWindow::eventFilter(QObject *obj, QEvent *event) {
    if (obj == ui->tableWidget->viewport()) {
        if (event->type() == QEvent::Enter) {
            m_mouseInTable = true;
        } else if (event->type() == QEvent::Leave) {
            m_mouseInTable = false;
        }
    }
    return QWidget::eventFilter(obj, event);
}

void MainWindow::showNetworkCard()
{
    int n = pcap_findalldevs(&all_device, errbuf);
    //pcap_findalldevs(&all_device, errbuf);

    if(n == -1)
    {
        ui->comboBox->addItem("error:" + QString(errbuf));
    }
    else
    {
        ui->comboBox->clear();
        ui->comboBox->addItem(" pls choose card!");
        for(device = all_device; device!=nullptr; device = device->next)
        {
            QString device_name = device->name;
            device_name.replace("\\Device\\", "");
            QString des = device->description;
            QString item = device_name + des;
            ui->comboBox->addItem(item);
        }
    }

}

int MainWindow::capture()
{
    if(device)
    {
        pointer = pcap_open_live(device->name, 65536, 1, 1000, errbuf);
    }
    else
    {
        return -1;
    }

    if(!pointer)
    {
        pcap_freealldevs(all_device);
        device = nullptr;
        return -1;
    }
    else
    {
        if(pcap_datalink(pointer) != DLT_EN10MB)
        {
            pcap_close(pointer);
            pcap_freealldevs(all_device);
            device = nullptr;
            pointer = nullptr;
            return -1;
        }
        statusBar()->showMessage(device->name);
    }
    return 0;
}

void MainWindow::on_comboBox_currentIndexChanged(int index)
{
    int i = 0;
    if(index != 0)
    {
        for(device = all_device; i<index -1; device = device->next, i++)
        {

        }
    }
    return;
}

void MainWindow::HandleMessage(DataPackAge data)
{
    //qDebug()<<data.getTimeStamp()<<" "<<data.getInfo();

    ui->tableWidget->insertRow(countNumber);
    this->pData.push_back(data);

    QString type = data.getPackageType();

    QColor color;

    if(type == "TCP")
    {
        color = QColor(216, 191, 216);
    }
    else if(type == "UDP")
    {
        color = QColor(144, 238, 144);
    }
    else if(type == "ARP")
    {
        color = QColor(216, 238, 0);
    }
    else if(type == "DNS")
    {
        color = QColor(255, 191, 255);
    }
    else if(type == "TCP")
    {
        color = QColor(78, 191, 34);
    }
    else if(type == "SSL")
    {
        color = QColor(4, 241, 34);
    }
    else if(type == "TLS")
    {
        color = QColor(238, 1, 134);
    }
    else
    {
        color = QColor(129, 266, 34);
    }
    ui->tableWidget->setItem(countNumber, 0, new QTableWidgetItem(QString::number(countNumber)));
    ui->tableWidget->setItem(countNumber, 1, new QTableWidgetItem(data.getTimeStamp()));
    ui->tableWidget->setItem(countNumber, 2, new QTableWidgetItem(data.getSource()));
    ui->tableWidget->setItem(countNumber, 3, new QTableWidgetItem(data.getDestination()));
    ui->tableWidget->setItem(countNumber, 4, new QTableWidgetItem(type));
    ui->tableWidget->setItem(countNumber, 5, new QTableWidgetItem(data.getDataLength()));
    ui->tableWidget->setItem(countNumber, 6, new QTableWidgetItem(data.getInfo()));

    for(int i = 0; i< 7; i++)
    {
        ui->tableWidget->item(countNumber, i)->setBackgroundColor(color);
    }

    if (!m_mouseInTable) {
        QTableWidgetItem* item = ui->tableWidget->item(countNumber, 0);
        if (item) {
            ui->tableWidget->scrollToItem(item, QAbstractItemView::EnsureVisible);
        }
    }

    countNumber++;
}

void MainWindow::icmpHandleMessage(QString info)
{
    //ui->treeWidget
    //qDebug()<<info;
    QTreeWidgetItem *item = new QTreeWidgetItem(QStringList()<<info);
    ui->treeWidget->addTopLevelItem(item);
}

void MainWindow::httpHandleMessage(QString position)
{
    if(position.size() < 20)
    {
        ui->lineEdit_6->setText(position);
    }
    else {
        ui->lineEdit_6->setText("try more!"+position);
    }
}


void MainWindow::on_tableWidget_cellClicked(int row, int column)
{
    if(row == numberRow || row < 0)
    {
        return;
    }
    else
    {
        ui->treeWidget->clear();
        numberRow = row;
        if(numberRow < 0 ||numberRow > countNumber)
        {
            return;
        }

        QString desMac = pData[numberRow].getDestination();
        QString srcMac = pData[numberRow].getSrcMacAddr();
        QString type = pData[numberRow].getMacType();
        QString tree = "Ethernet, Src: " + srcMac + " Dst: " + desMac;

        QTreeWidgetItem *item = new QTreeWidgetItem(QStringList()<<tree);

        ui->treeWidget->addTopLevelItem(item);

        item->addChild(new QTreeWidgetItem(QStringList() << "Destination : " + desMac));
        item->addChild(new QTreeWidgetItem(QStringList() << "Source : " + srcMac));
        item->addChild(new QTreeWidgetItem(QStringList() << "Type : " + type));
    }
}


void MainWindow::on_pushButton_clicked()
{
    QString ip_name = ui->lineEdit_2->text();
    QString max_hop = ui->lineEdit_3->text();
    QString timeout = ui->lineEdit_4->text();
    QString padding = ui->lineEdit_7->text();
    sender->setMaxHop(max_hop.toUtf8().toInt());
    sender->setTimeOut(timeout.toUtf8().toInt());
    sender->setIpName(ip_name);
    sender->setPadding(padding);

    if(!sender->isRunning())
    {
        sender->start();
    }
    else
    {
        return;
    }
}


void MainWindow::on_pushButton_2_clicked()
{
    if(sender->isRunning())
    {
        sender->setKill();
        sender->quit();
        sender->wait();
    }
    else
    {
        return;
    }
}


void MainWindow::on_lineEdit_5_returnPressed()
{

}


void MainWindow::on_pushButton_3_clicked()
{
    QString ip = ui->lineEdit_5->text();
    http->SetIpAddr(ip);
    http->start();
}

